package com.bto.solar.work.service;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.bto.solar.work.common.BizException;
import com.bto.solar.work.common.RedisService;
import com.bto.solar.work.config.ConfigParams;
import com.bto.solar.work.constant.BizCode;
import com.bto.solar.work.constant.BizStageEnum;
import com.bto.solar.work.constant.BizTaskEnum;
import com.bto.solar.work.constant.Constants;
import com.bto.solar.work.constant.DBConstants;
import com.bto.solar.work.dao.IAppointService;
import com.bto.solar.work.dao.ICompanyService;
import com.bto.solar.work.dao.IDepartmentService;
import com.bto.solar.work.dao.IOrderBaseService;
import com.bto.solar.work.dao.IPermissionsService;
import com.bto.solar.work.dao.IRoleService;
import com.bto.solar.work.dao.IUserService;
import com.bto.solar.work.dto.CreateUserReq;
import com.bto.solar.work.dto.QueryUserReq;
import com.bto.solar.work.dto.RegisterUserReq;
import com.bto.solar.work.dto.UpdatePasswordReq;
import com.bto.solar.work.entity.Appoint;
import com.bto.solar.work.entity.Company;
import com.bto.solar.work.entity.Department;
import com.bto.solar.work.entity.OrderBase;
import com.bto.solar.work.entity.Permissions;
import com.bto.solar.work.entity.Role;
import com.bto.solar.work.entity.User;
import com.bto.solar.work.utils.JsonToListUtils;
import com.bto.solar.work.utils.NullUtils;
import com.bto.solar.work.utils.ServletUtils;
import com.bto.solar.work.utils.StringUtils;
import com.bto.solar.work.utils.tree.TreeUtils;
import com.bto.solar.work.vo.UserVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;


@Slf4j
@Service
public class BtoUserService {

    @Autowired
    private IRoleService roleService;
    @Autowired
    private IUserService userService;
    @Autowired
    private ICompanyService companyService;
    @Autowired
    private IDepartmentService departmentService;
    @Autowired
    private IPermissionsService permissionsService;
    @Autowired
    private IOrderBaseService orderService;
    @Autowired
    private IAppointService appointService;
    @Autowired
    @Lazy
    private BtoCompanyService btoCompanyService;
    @Autowired
    @Lazy
    private BtoPermissionService btoPermissionService;
    @Autowired
    private RedisService redisService;

    @Autowired
    private ConfigParams configParams;
    @Value("${bto.allow-update-order-info-user-ids}")
    private String allowUpdateOrderInfoUserIds;
    @Value("${bto.default-password}")
    private String defaultPassword;


    /**
     * 通过userId获取user对象信息
     */
    public User getUserByUserId(Long userId) {
        //判断userId是否为空
        if (NullUtils.isNull(userId)) {
            throw new BizException(BizCode.PARAM_ERROR);
        }
        //通过userId获取User信息
        User dbUser = userService.lambdaQuery()
                .eq(User::getUserId, userId)
                .eq(User::getApprove, DBConstants.USER_APPROVE_PASS)//审核通过
                .eq(User::getStatus, DBConstants.USER_STATUS_NORMAL)//状态正常
                .one();
        if (null == dbUser) {
            throw new BizException("用户不存在 或者 用户处于待审核 或者 用户处于禁用");
        }
        return dbUser;
    }

    /**
     * 根据查询条件分页显示用户信息
     */
    public Page<UserVO> getUserInfosByPage(QueryUserReq queryUserReq) {
        if (NullUtils.isNull(queryUserReq.getCurrentPage())) {
            queryUserReq.setCurrentPage(1);
        }
        if (NullUtils.isNull(queryUserReq.getPageSize())) {
            queryUserReq.setPageSize(10);
        }
        if (NullUtils.isNull(queryUserReq.getOrderBy())) {
            queryUserReq.setOrderBy(Boolean.TRUE);
        }
        return getUserInfosByPage(queryUserReq.getCurrentPage(), queryUserReq.getPageSize(),
                queryUserReq.getCompanyId(), queryUserReq.getStatus(), queryUserReq.getPermissionName(),
                queryUserReq.getQueryValue(), queryUserReq.getQueryUserId(), queryUserReq.getApprove(),
                queryUserReq.getOrderBy());
    }

    /**
     * 根据查询条件分页显示用户信息
     */
    public Page<UserVO> getUserInfosByPage(Integer currentPage, Integer pageSize,
                                           Long companyId, Byte status,
                                           String permissionName, String queryValue,
                                           Long queryUserId, String approve, boolean orderBy) {

        //获取登录者的用户信息
        User loginUser = this.getCurrentUser();
        //登录者不存在、登录者没有角色
        if (null == loginUser || StringUtils.isBlank(loginUser.getRolesIds())) {
            log.error("用户查询接口：登录者信息不存在 或者 登录者没有角色信息");
            return new Page<>();
        }
        //查询登录者的角色信息
        List<String> roleIds = JSONArray.parseArray(loginUser.getRolesIds(), String.class);
        if (NullUtils.isEmpty(roleIds)) {
            log.error("登录者没有角色信息");
            return new Page<>();
        }
        //判断登录者
        boolean isSupperAdmin = isUserSuperAdmin(loginUser);

        //通过companyId查询用户公司信息
        Company loginCompany = btoCompanyService.getCompanyByUser(loginUser);
        if (null == loginCompany) {
            log.error("登录者没有公司信息");
            return new Page<>();
        }

        //包含超级管理员的用户列表
        List<User> superAdminUserList = new ArrayList<>();
        //如果不是超级管理员，查不出超级管理员
        if (!isSupperAdmin) {
            superAdminUserList = getUsersByRole(DBConstants.ROLE_SUPER_ADMIN);
        }

        List<User> userList = userService.lambdaQuery()
                .ne(User::getUserId, loginUser.getUserId())
                .notIn(NullUtils.isNotEmpty(superAdminUserList), User::getUserId, superAdminUserList)//不包含超级管理员用户列表
                .eq(!isSupperAdmin && !DBConstants.COMPANY_TYPE_HEAD_OFFICE.equals(loginCompany.getType()), User::getCompanyId, loginUser.getCompanyId())
                .list();

        //不是超管又不是总部有部门限制
        if (!isSupperAdmin && !DBConstants.COMPANY_TYPE_HEAD_OFFICE.equals(loginCompany.getType())) {
            if (StringUtils.isBlank(loginUser.getDepartmentIds())) {
                log.error("登录者没有部门信息，无法显示其他用户信息");
                return new Page<>();
            }
            //登录者的部门列表
            List<Long> departmentIdByLogin = JSONArray.parseArray(loginUser.getDepartmentIds(), Long.class);
            userList = filterDepartmentByUserList(userList, departmentIdByLogin);
        }

        //筛选后userId列表
        List<Long> userIds = userList.stream().map(User::getUserId).collect(Collectors.toList());
        if (NullUtils.isEmpty(userIds)) {
            return new Page<>();
        }

        //分页参数
        Page<User> userPage = new Page<>(currentPage, pageSize);

        //登陆Id，公司Id，状态，查询参数，userIds，分页参数，查询用户ID
        Page<User> usersList = userService.getUserByPage(loginUser.getUserId(), companyId,
                status, queryValue, userIds, queryUserId, userPage, approve, orderBy, permissionName);

        Map<Long, Company> companyMap = companyService.list().stream().collect(Collectors.toMap(Company::getCompanyId, company -> company));
        Map<Long, Department> departmentMap = departmentService.list().stream().collect(Collectors.toMap(Department::getDepartmentId, department -> department));

        Map<String, Permissions> permissionsMap = permissionsService.lambdaQuery()
                .list().stream().collect(Collectors.toMap(Permissions::getName, permissions -> permissions));

        Map<String, Role> roleMap = roleService.lambdaQuery()
                .list().stream()
                .collect(Collectors.toMap(Role::getName, role -> role));

        List<UserVO> userVoList = new ArrayList<>();
        for (User dbUser : usersList.getRecords()) {
            dbUser.setPassword(null);
            UserVO userVO = new UserVO();
            BeanUtils.copyProperties(dbUser, userVO);

            //公司
            UserVO.Company company = new UserVO.Company();
            company.setCompanyId(dbUser.getCompanyId());
            company.setName(companyMap.get(dbUser.getCompanyId()).getName());
            userVO.setCompany(company);

            //部门
            if (StringUtils.isNotBlank(dbUser.getDepartmentIds())) {
                List<Long> departmentIds = JSONArray.parseArray(dbUser.getDepartmentIds(), Long.class);
                userVO.setDepartmentIds(null);
                if (NullUtils.isNotEmpty(departmentIds)) {
                    List<UserVO.Department> departmentList = new ArrayList<>();
                    for (Long departmentId : departmentIds) {
                        UserVO.Department department = new UserVO.Department();
                        if (departmentMap.containsKey(departmentId)) {
                            department.setDepartmentId(departmentId);
                            department.setName(departmentMap.get(departmentId).getName());
                            departmentList.add(department);
                        }
                    }
                    userVO.setDepartmentList(departmentList);
                }
            }

            //权限列表
            if (StringUtils.isNotBlank(dbUser.getPermissionIds())) {
                List<String> permissionIds = JSONArray.parseArray(dbUser.getPermissionIds(), String.class);
                userVO.setPermissionIds(null);
                if (NullUtils.isNotEmpty(permissionIds)) {
                    List<UserVO.Permissions> permissionList = new ArrayList<>();
                    for (String permissionId : permissionIds) {
                        UserVO.Permissions permissions = new UserVO.Permissions();
                        if (permissionsMap.containsKey(permissionId)) {
                            Permissions permissionsByDb = permissionsMap.get(permissionId);
                            permissions.setName(permissionsByDb.getName());
                            permissions.setChineseName(permissionsByDb.getChineseName());
                            permissionList.add(permissions);
                        }
                    }
                    userVO.setPermissionList(permissionList);
                }
            }


            //APP管理员
            if (StringUtils.isNotBlank(dbUser.getRolesIds())) {
                List<String> roleIdList = JSONArray.parseArray(dbUser.getRolesIds(), String.class);
                userVO.setRolesIds(null);
                if (NullUtils.isNotEmpty(roleIdList)) {
                    List<UserVO.Role> roleList = new ArrayList<>();
                    for (String roleName : roleIdList) {
                        UserVO.Role role = new UserVO.Role();
                        if (roleMap.containsKey(roleName)) {
                            Role roleByDb = roleMap.get(roleName);
                            role.setName(roleByDb.getName());
                            role.setChineseName(roleByDb.getChineseName());
                            roleList.add(role);
                        }
                    }
                    userVO.setAdminList(roleList);
                }
            }
            userVoList.add(userVO);
        }

        Page<UserVO> userVoPage = new Page<>();
        BeanUtils.copyProperties(userPage, userVoPage);
        userVoPage.setRecords(userVoList);
        return userVoPage;
    }

    //通过部门筛选出来的用户列表
    public List<User> filterDepartmentByUserList(List<User> userList, List<Long> departmentIdByLogin) {
        List<User> userNewList = new ArrayList<>();
        List<Long> queryListByLong = new ArrayList<>();
        //获取部门列表
        List<UserVO.Department> departmentAllList = getDepartmentAllList();
        //登录者的自己部门和下属部门列表
        for (Long departmentId : departmentIdByLogin) {
            queryListByLong.addAll(TreeUtils.getIdList(departmentAllList, departmentId));
        }
        for (User user : userList) {
            if (StringUtils.isNotBlank(user.getDepartmentIds())) {
                //用户的部门列表
                List<Long> departmentIdByList = JSONArray.parseArray(user.getDepartmentIds(), Long.class);
                if (NullUtils.isNotEmpty(departmentIdByList)) {
                    for (Long departmentId : departmentIdByList) {
                        if (queryListByLong.contains(departmentId)) {
                            userNewList.add(user);
                        }
                    }
                }
            }
        }
        return userNewList;
    }

    //通过权限筛选出来的用户列表
    public List<User> filterCategoryIdByUserList(List<User> userList, User loginUser, String permissionId) {
        List<User> userNewList = new ArrayList<>();
        for (User user : userList) {
            if (StringUtils.isNotBlank(user.getPermissionIds())) {
                //用户的权限列表
                List<String> permissionIdList = JSONArray.parseArray(loginUser.getPermissionIds(), String.class);
                if (NullUtils.isNotEmpty(permissionIdList)) {
                    if (permissionIdList.contains(permissionId)) {
                        userNewList.add(user);
                    }
                }
            }
        }
        return userNewList;
    }

    public List<UserVO.Department> getDepartmentAllList() {
        return departmentService.list().stream().map(department -> {
            UserVO.Department departmentVO = new UserVO.Department();
            departmentVO.setDepartmentId(department.getDepartmentId());
            departmentVO.setName(department.getName());
            departmentVO.setParentId(department.getParentId());
            return departmentVO;
        }).collect(Collectors.toList());
    }


    /**
     * 获取用户个人中心信息
     *
     * @return
     */
    public UserVO getUserInfo(Long userId) {
        UserVO userVO = new UserVO();
        User user = null;
        if (NullUtils.isNotNull(userId)) {
            user = getUserByUserId(userId);
        } else {
            user = getCurrentUser();
        }
        BeanUtils.copyProperties(user, userVO);

        userVO.setPassword(null);

        Company company = companyService.getById(user.getCompanyId());
        UserVO.Company userCompany = new UserVO.Company();
        userCompany.setCompanyId(company.getCompanyId());
        userCompany.setName(company.getName());
        userVO.setCompany(userCompany);

        //部门
        if (StringUtils.isNotBlank(user.getDepartmentIds())) {
            userVO.setDepartmentIds(null);
            List<Long> departmentIds = JSONArray.parseArray(user.getDepartmentIds(), Long.class);
            if (NullUtils.isNotEmpty(departmentIds)) {
                List<Department> departments = departmentService.lambdaQuery()
                        .in(Department::getDepartmentId, departmentIds).list();
                List<UserVO.Department> departmentList = new ArrayList<>();
                for (Department department : departments) {
                    UserVO.Department userDepartment = new UserVO.Department();
                    userDepartment.setDepartmentId(department.getDepartmentId());
                    userDepartment.setName(department.getName());
                    departmentList.add(userDepartment);
                }
                userVO.setDepartmentList(departmentList);
            }
        }


        //权限列表
        if (StringUtils.isNotBlank(user.getPermissionIds())) {
            List<String> permissionIds = JSONArray.parseArray(user.getPermissionIds(), String.class);
            userVO.setPermissionIds(null);
            if (NullUtils.isNotEmpty(permissionIds)) {
                List<UserVO.Permissions> permissionList = new ArrayList<>();
                List<Permissions> permissions = permissionsService.lambdaQuery()
                        .in(Permissions::getName, permissionIds).list();
                for (Permissions permission : permissions) {
                    UserVO.Permissions userPermission = new UserVO.Permissions();
                    userPermission.setName(permission.getName());
                    userPermission.setChineseName(permission.getChineseName());
                    permissionList.add(userPermission);
                }
                userVO.setPermissionList(permissionList);
            }
        }

        //角色
        if (StringUtils.isNotBlank(user.getRolesIds())) {
            List<String> roleIdList = JSONArray.parseArray(user.getRolesIds(), String.class);
            userVO.setRolesIds(null);
            if (NullUtils.isNotEmpty(roleIdList)) {
                List<UserVO.Role> roleList = new ArrayList<>();
                List<Role> roles = roleService.lambdaQuery()
                        .in(Role::getName, roleIdList).list();
                for (Role role : roles) {
                    UserVO.Role userRole = new UserVO.Role();
                    userRole.setName(role.getName());
                    userRole.setChineseName(role.getChineseName());
                    roleList.add(userRole);
                }
                userVO.setAdminList(roleList);
            }
        }

        return userVO;

    }

    /**
     * 用户注册
     */
    public void registerUser(RegisterUserReq registerUserReq) {
        User user = new User();
        BeanUtils.copyProperties(registerUserReq, user);


        User dbUser = userService.lambdaQuery()
                .eq(User::getPhone, registerUserReq.getPhone())
                .or().eq(User::getAccount, registerUserReq.getAccount())
                .or().eq(StringUtils.isNotBlank(registerUserReq.getEmail()), User::getEmail, registerUserReq.getEmail()).one();

        //判断手机号是否已存在（不管用户状态是正常还是禁用）
        if (NullUtils.isNotNull(dbUser)) {
            if (dbUser.getPhone().equals(registerUserReq.getPhone())) {
                throw new BizException(BizCode.USER_PHONE_EXIST_ERROR);
            } else if (dbUser.getAccount().equals(registerUserReq.getAccount())) {
                throw new BizException("账号已存在!");
            } else {
                throw new BizException("邮箱已存在!");
            }
        }

        //查询公司是否存在
        Company company = companyService.lambdaQuery().eq(Company::getCompanyId, user.getCompanyId()).one();
        if (null == company) {
            throw new BizException(BizCode.COMPANIES_ABSENT_ERROR);
        }
        //校验密码长度
        if (user.getPassword().length() < Constants.PASSWORD_LENGTH) {
            throw new BizException("密码长度不能小于6位");
        }
        //校验可创建业务
        if (NullUtils.isNotEmpty(registerUserReq.getPermissionList())) {
            List<Permissions> permissionListByDb = permissionsService.lambdaQuery()
                    .in(Permissions::getName, registerUserReq.getPermissionList())
                    .eq(Permissions::getGuardName, DBConstants.CREATE_ORDER_CATEGORY_GROUP)
                    .list();
            if (NullUtils.isEmpty(permissionListByDb)) {
                throw new BizException("权限列表必须包含可创建业务的权限！");
            }
            Set<String> permissionListBySet = new HashSet<>(registerUserReq.getPermissionList());
            JSONArray jsonByPermission = JSONArray.parseArray(JSON.toJSONString(permissionListBySet));
            user.setPermissionIds(jsonByPermission.toJSONString());
        } else {
            throw new BizException("可创建业务不能为空！");
        }
        //审核--待审核
        user.setApprove(DBConstants.USER_APPROVE_WAITING);
        //状态--禁用
        user.setStatus(DBConstants.USER_STATUS_DISABLE);
        //来源--APP
        user.setSource(DBConstants.USER_SOURCE_APP);
        //角色--普通用户
        List<String> userRoles = new ArrayList<>();
        userRoles.add(DBConstants.ROLE_USER);
        JSONArray jsonByRoles = JSONArray.parseArray(JSON.toJSONString(userRoles));
        user.setRolesIds(jsonByRoles.toJSONString());

        userService.save(user);

    }

    /**
     * 审核用户
     */
    public void approveUser(Long userId, String approve) {
        User user = userService.getById(userId);
        if (NullUtils.isNull(user)) {
            throw new BizException(BizCode.PARAM_ERROR);
        }
        //更新用户审核
        LambdaUpdateWrapper<User> updateWrapper = new LambdaUpdateWrapper<>();

        if (DBConstants.USER_APPROVE_PASS.equals(approve)) {
            //状态--正常 审核-通过
            updateWrapper.eq(User::getUserId, userId)
                    .set(User::getApprove, approve)
                    .set(User::getStatus, DBConstants.USER_STATUS_NORMAL);
        } else if (DBConstants.USER_APPROVE_REJECT.equals(approve)) {
            //审核--审核拒绝
            updateWrapper.eq(User::getUserId, userId)
                    .set(User::getApprove, approve);
        } else {
            throw new BizException("审核类型不正确！");
        }

        userService.update(null, updateWrapper);
    }

    /**
     * 用户新增
     */
    public boolean addUser(CreateUserReq createUserReq) {

        //对必填项进行判断是否为空，防止空指针
        if (NullUtils.isNull(createUserReq)) {
            throw new BizException(BizCode.PARAM_ERROR);
        }

        boolean addOperation = true;
        User user = new User();
        //判断新增用户信息和补充user信息
        this.decideUser(createUserReq, user, addOperation);

        //新增用户信息
        return userService.save(user);
    }

    /**
     * 更新用户信息
     */
    public boolean updateUser(CreateUserReq createUserReq) {

        //对必填项进行判断是否为空，防止空指针
        if (NullUtils.isNull(createUserReq)) {
            throw new BizException(BizCode.PARAM_ERROR);
        }

        boolean addOperation = false;
        User user = new User();
        //判断新增用户信息和补充user信息
        this.decideUser(createUserReq, user, addOperation);

        //更新用户信息
        LambdaUpdateWrapper<User> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(User::getUserId, user.getUserId());
        return userService.update(user, updateWrapper);
    }

    /**
     * 重置密码
     */
    public boolean resetPassword(Long userId) {
        User loginUser = getCurrentUser();
        //对必填项进行判断是否为空，防止空指针
        if (NullUtils.isNull(userId)) {
            throw new BizException(BizCode.PARAM_ERROR);
        }
        //判断用户是否存在
        User dbUser = userService.getById(userId);
        if (NullUtils.isNull(dbUser)) {
            throw new BizException(BizCode.USER_ABSENT_ERROR);
        }
        //校验是否有权限删除超级管理员
        isSuperAdminByUpdate(dbUser, loginUser);
        //更新用户密码信息
        LambdaUpdateWrapper<User> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(User::getUserId, userId).set(User::getPassword, defaultPassword);
        return userService.update(null, updateWrapper);
    }

    /**
     * 删除用户
     */
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteUser(Long userId) {

        User loginUser = getCurrentUser();
        if (NullUtils.isNull(userId)) {
            throw new BizException(BizCode.PARAM_ERROR);
        }
        //判断用户是否存在
        User dbUser = userService.getById(userId);
        if (NullUtils.isNull(dbUser)) {
            throw new BizException(BizCode.USER_ABSENT_ERROR);
        }
        //校验是否有权限删除超级管理员
        isSuperAdminByUpdate(dbUser, loginUser);

        long order = orderService.lambdaQuery().eq(OrderBase::getUserId, userId).count();
        if (order > 0) {
            throw new BizException("该用户有相关订单，不能删除");
        }
        //删除用户
        return userService.removeById(userId);
    }

    /**
     * 修改用户状态
     */
    public boolean updateStatus(Long userId, Byte status) {
        //登录者
        User loginUser = getCurrentUser();
        if (NullUtils.isNull(userId) || NullUtils.isNull(status)
                || status < 0 || status > 1) {
            throw new BizException(BizCode.PARAM_ERROR);
        }
        User dbUser = userService.lambdaQuery().eq(User::getUserId, userId)
                .eq(User::getApprove, DBConstants.USER_APPROVE_PASS).one();
        if (NullUtils.isNull(dbUser)) {
            throw new BizException(BizCode.USER_ABSENT_ERROR);
        }

        //校验是否有权限修改超级管理员
        isSuperAdminByUpdate(dbUser, loginUser);

        //更新用户密码信息
        LambdaUpdateWrapper<User> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(User::getUserId, userId).set(User::getStatus, status);
        return userService.update(null, updateWrapper);
    }

    /**
     * 用户新增或者用户更新对用户信息进行校验
     */
    public void decideUser(CreateUserReq createUserReq, User user, boolean addOperation) {

        if (NullUtils.isNull(createUserReq)) {
            throw new BizException(BizCode.PARAM_ERROR);
        }

        BeanUtils.copyProperties(createUserReq, user);

        //获取当前用户
        long start = System.currentTimeMillis();
        User loginUser = this.getCurrentUser();
        log.info("查询"+ (System.currentTimeMillis() - start));
        if (null == loginUser) {
            throw new BizException(BizCode.USER_ABSENT_ERROR);
        }
        //Company loginCompany = btoCompanyService.getCompanyByUser(loginUser);

        //判断用户手机号是否存在
        User dbUser;
        if (addOperation) {
            //密码校验
            if (StringUtils.isEmpty(createUserReq.getPassword()) || createUserReq.getPassword().length() < Constants.PASSWORD_LENGTH) {
                throw new BizException("密码不能为空或者不鞥小于6位数！");
            }
            dbUser = userService.lambdaQuery()
                    .eq(User::getPhone, createUserReq.getPhone())
                    .or().eq(User::getAccount, createUserReq.getAccount())
                    .or().eq(User::getPhone, createUserReq.getAccount())
                    .or().eq(User::getAccount, createUserReq.getPhone())
                    .or().eq(StringUtils.isNotBlank(createUserReq.getEmail()), User::getEmail, createUserReq.getEmail()).one();
        } else {
            User updateUser = getUserByUserId(createUserReq.getUserId());
            if (updateUser == null) {
                throw new BizException("修改的用户不存在！");
            }
            //校验是否有权限修改超级管理员
            isSuperAdminByUpdate(updateUser, loginUser);

            //不包含更改用户ID--手机号 账号 邮箱
            dbUser = userService.lambdaQuery()
                    .ne(User::getUserId, createUserReq.getUserId())
                    .and(query -> query.eq(User::getPhone, createUserReq.getPhone())
                            .or().eq(User::getAccount, createUserReq.getAccount())
                            .or().eq(User::getPhone, createUserReq.getAccount())
                            .or().eq(User::getAccount, createUserReq.getPhone())
                            .or().eq(StringUtils.isNotBlank(createUserReq.getEmail()), User::getEmail, createUserReq.getEmail())
                    )
                    .one();
        }

        //判断手机号是否已存在（不管用户状态是正常还是禁用）
        if (NullUtils.isNotNull(dbUser)) {
            if (dbUser.getPhone().equals(createUserReq.getPhone())) {
                throw new BizException(BizCode.USER_PHONE_EXIST_ERROR);
            } else if (dbUser.getAccount().equals(createUserReq.getAccount())) {
                throw new BizException("账号已存在!");
            } else if (dbUser.getPhone().equals(createUserReq.getAccount())) {
                throw new BizException("该账号被其他人当作手机号使用了，请使用其他账号名称！");
            } else if (dbUser.getAccount().equals(createUserReq.getPhone())) {
                throw new BizException("该手机号被其他人当作账号使用了，请使用其他手机号码！");
            } else {
                throw new BizException("邮箱已存在!");
            }

        }

        //判断公司是否存在
//        Company dbCompany = companyService.lambdaQuery()
//                .eq(Company::getCompanyId, createUserReq.getCompanyId()).one();
//        if (NullUtils.isNull(dbCompany)) {
//            throw new BizException(BizCode.NOT_HAVE_COMPANY_ERROR);
//        }

        //如果不是超级管理员又不是总部，companyId必须与登录者的一致
//        List<String> roleIds = JsonToListUtils.convertJSONArrayToStringList(loginUser.getRolesIds());
//        if (!roleIds.contains(DBConstants.ROLE_SUPER_ADMIN)
//                && (!DBConstants.COMPANY_TYPE_HEAD_OFFICE.equals(loginCompany.getType())
//                && (!createUserReq.getCompanyId().equals(loginUser.getCompanyId())))) {
//            throw new BizException(BizCode.ACCESS_DENIED);
//        }

        //通过公司ID来查询对应的部门Id列表，并且判断部门Id是否存在
        if (NullUtils.isNotEmpty(createUserReq.getDepartmentIds())) {
//            List<Department> departments = departmentService.lambdaQuery()
//                    .eq(Department::getCompanyId, createUserReq.getCompanyId())
//                    .in(Department::getDepartmentId, createUserReq.getDepartmentIds())
//                    .list();
//            if (createUserReq.getDepartmentIds().size() != departments.size()) {
//                throw new BizException("部门数据异常！");
//            }
            Set<Long> departmentIdsBySet = new HashSet<>(createUserReq.getDepartmentIds());
            user.setDepartmentIds(departmentIdsBySet.toString());
        }

        //判断权限中是否包含可创建业务的权限存在
        if (NullUtils.isNotEmpty(createUserReq.getPermissionList())) {
//            List<Permissions> permissionListByDb = permissionsService.lambdaQuery()
//                    .in(Permissions::getName, createUserReq.getPermissionList())
//                    //.eq(Permissions::getGuardName, DBConstants.CREATE_ORDER_CATEGORY_GROUP)
//                    .list();
//            if (createUserReq.getPermissionList().size() != permissionListByDb.size()) {
//                throw new BizException("权限列表数据异常！");
//            }
            Set<String> permissionListBySet = new HashSet<>(createUserReq.getPermissionList());
            JSONArray jsonByPermission = JSONArray.parseArray(JSON.toJSONString(permissionListBySet));
            user.setPermissionIds(jsonByPermission.toJSONString());
        }

        //新增用户的角色列表
        List<String> userRoles = new ArrayList<>();
        //判断管理员列表是否存在
        if (NullUtils.isNotEmpty(createUserReq.getRolesIds())) {
            List<String> roleIds = createUserReq.getRolesIds();
            //判断登陆者是否可以创建用户实体包含超级管理员角色
            checkCreateUserHasSuperAdmin(roleIds, loginUser);
            userRoles.addAll(createUserReq.getRolesIds());
        } else {
            //设置默认值为普通用户角色
            userRoles.add(DBConstants.ROLE_USER);
        }
        Set<String> userRolesBySet = new HashSet<>(userRoles);
        JSONArray jsonByRoles = JSONArray.parseArray(JSON.toJSONString(userRolesBySet));
        user.setRolesIds(jsonByRoles.toJSONString());

        //性别--未知
        if (NullUtils.isNull(user.getGender())) {
            user.setGender(DBConstants.USER_GENDER_NUKNOW);
        }
        //后台新增用户才会设置默认值
        if (addOperation) {
            //后台添加
            user.setSource(DBConstants.USER_SOURCE_WEB);
            //审核 -- 审核通过
            user.setApprove(DBConstants.USER_APPROVE_PASS);
            //正常
            user.setStatus(DBConstants.USER_STATUS_NORMAL);
        }

    }

    /**
     * 通过公司id获取用户列表（公司下的员工）
     */
    public List<User> getUsersByCompanyId(Long companyId) {
        return userService.lambdaQuery().eq(User::getCompanyId, companyId)
                .eq(User::getApprove, DBConstants.USER_APPROVE_PASS)
                .eq(User::getDeleted, false)
                .list();
    }

    /**
     * 通过部门ID获取用户列表（部门下的员工）
     */
    public List<User> getUsersByDepartmentId(Long departmentId) {
        List<User> users = userService.lambdaQuery().eq(User::getDeleted, false).list();
        List<User> result = new ArrayList<>();
        users.forEach(user -> {
            List<Long> departmentIds = JsonToListUtils.convertJSONArrayToList(user.getDepartmentIds());
            if (departmentIds.contains(departmentId)) {
                result.add(user);
            }
        });
        return result;
    }

    /**
     * 判断用户是否是超级管理员
     */
    public boolean isUserSuperAdmin(Long userId) {
        User user = userService.getById(userId);
        List<String> roleIds = JsonToListUtils.convertJSONArrayToStringList(user.getRolesIds());
        return roleIds.contains(DBConstants.ROLE_SUPER_ADMIN);
    }

    /**
     * 判断用户是否是超级管理员
     */
    public boolean isUserSuperAdmin(User user) {
        if (StringUtils.isNotBlank(user.getRolesIds())) {
            List<String> roleIds = JSONArray.parseArray(user.getRolesIds(), String.class);
            if (NullUtils.isNotEmpty(roleIds)) {
                return roleIds.contains(DBConstants.ROLE_SUPER_ADMIN);
            } else {
                return false;
            }
        } else {
            return false;
        }
    }

    /**
     * 判断登陆者是否可以创建用户实体包含超级管理员角色
     */
    public void checkCreateUserHasSuperAdmin(List<String> roleIds, User loginUser) {
        //包含超级管理员权限
        if (roleIds.contains(DBConstants.ROLE_SUPER_ADMIN)) {
            //登录者不是超级管理员 - 不能创建
            if (!isUserSuperAdmin(loginUser)) {
                throw new BizException("你不是超级管理员，无法创建超级管理员");
            }
        }
    }

    /**
     * 判断用户ID是否是总公司员工
     */
    public boolean isUserBelongHeadCompany(Long userId) {
        User user = getUserByUserId(userId);
        if (user == null) {
            throw new BizException(BizCode.PARAM_ERROR);
        }
        Company company = btoCompanyService.getCompanyByUser(user);
        return DBConstants.COMPANY_TYPE_HEAD_OFFICE.equals(company.getType());
    }


    public Company getUserCompany(Long userId) {
        User user = getUserByUserId(userId);
        if (NullUtils.isNull(user)) {
            throw new BizException("不存在用户 {}", userId);
        }
        return btoCompanyService.getCompanyByUser(user);
    }

    public Company getCurrentUserCompany() {
        Integer userId = ServletUtils.getHeaderToInt(Constants.HEADER_USER_ID);
        User user = getUserByUserId(Long.valueOf(userId));
        if (NullUtils.isNull(user)) {
            throw new BizException("不存在用户 {}", userId);
        }
        return btoCompanyService.getCompanyByUser(user);
    }

    /**
     * 判断用户是否是总公司员工
     */
    public boolean isUserBelongHeadCompany(User user) {
        Company company = btoCompanyService.getCompanyByUser(user);
        return DBConstants.COMPANY_TYPE_HEAD_OFFICE.equals(company.getType());
    }

    /**
     * 判断当前用户是否是总公司员工
     */
    public boolean isCurrentUserBelongHeadCompany() {
        Company company = btoCompanyService.getCompanyByUser(getCurrentUser());
        return DBConstants.COMPANY_TYPE_HEAD_OFFICE.equals(company.getType());
    }


    /**
     * 获取系统当前登录用户
     */
    public User getCurrentUser() {
        Integer userId = ServletUtils.getHeaderToInt(Constants.HEADER_USER_ID);
        return getUserByUserId(Long.valueOf(userId));
    }


    /**
     * 判断当前用户，是否可以编辑阶段任务信息
     * 状态：订单任务只有-待填写状态才能编辑，其他状态都不能编辑
     * 人员：
     * 1、订单创建者可以编辑，
     * 2、技术勘察委派-可以编辑技术勘察信息
     * 3、设计阶段-博通总部设计人员可以编辑初设评审信息
     * 4、系统特殊怕配置
     */
    public boolean isCurrentUserCanEditOrderInfo(String orderId, String stageId, String taskId) {
        User currentUser = getCurrentUser();
        Long userId = currentUser.getUserId();

        //系统特殊配置用户
        if (configParams.getAllowUpdateOrderInfoUserIds().contains(String.valueOf(userId))) {
            return true;
        }

        boolean isJSKC = BizStageEnum.KAN_CHA.getStageId().equals(stageId) && BizTaskEnum.TASK_JSKC.getTaskId().equals(taskId);
        //创建订单本尊
        OrderBase orderBase = orderService.getById(orderId);
        if (orderBase.getUserId().equals(userId)) {
            if (!isJSKC) {
                return true;
            }
        }

        //委派目前只能是:技术踏勘
        if(isJSKC){
            //委派用户编辑
            List<Appoint> appoints = appointService.lambdaQuery().eq(Appoint::getUserId, userId).list();
            List<Appoint> collect = appoints.stream().filter(appoint -> {
                if (BizStageEnum.KAN_CHA.getStageId().equals(appoint.getStageId()) &&
                        BizTaskEnum.TASK_JSKC.getTaskId().equals(appoint.getTaskId()) &&
                        appoint.getUserId().equals(userId)) {
                    return true;
                }
                return false;
            }).collect(Collectors.toList());
            if(NullUtils.isNotEmpty(collect)){
                return true;
            }
            else {
                return false;
            }
        }


        boolean hasPermission = DBConstants.USER_CAN_EDIT_ORDER_PER.stream().anyMatch(permission -> currentUser.getPermissionIds().contains(permission));
        return hasPermission;

//        //委派目前只能是:技术踏勘
//        if(isJSKC){
//            //委派用户编辑
//            List<Appoint> appoints = appointService.lambdaQuery().eq(Appoint::getUserId, userId).list();
//            List<Appoint> collect = appoints.stream().filter(appoint -> {
//                if (BizStageEnum.KAN_CHA.getStageId().equals(appoint.getStageId()) &&
//                        BizTaskEnum.TASK_JSKC.getTaskId().equals(appoint.getTaskId()) &&
//                        appoint.getUserId().equals(userId)) {
//                    return true;
//                }
//                return false;
//            }).collect(Collectors.toList());
//            if(NullUtils.isNotEmpty(collect)){
//                return true;
//            }
//        }
//
//        //设计阶段-初审评审信息
//        if (BizStageEnum.DESIGN.getStageId().equals(stageId) && BizTaskEnum.TASK_CSPSXX.getTaskId().equals(taskId)) {
//            List<Permissions> userPermission = btoPermissionService.getPermissionListByUserId(userId);
//            return userPermission.stream().anyMatch(permissions -> {
//                return DBConstants.PER_DESIGN.equals(permissions.getName());
//            });
//        }
//        return false;
    }

    public boolean isCurrentUserCanEditOrderInfo(String orderId, String stageId, String taskId, List<String> editList) {
        User currentUser = getCurrentUser();
        Long userId = currentUser.getUserId();

        //系统特殊配置用户
        if (configParams.getAllowUpdateOrderInfoUserIds().contains(String.valueOf(userId))) {
            return true;
        }

        if (StringUtils.isEmpty(editList)) {
            return false;
        }

        boolean isJSKC = BizStageEnum.KAN_CHA.getStageId().equals(stageId) && BizTaskEnum.TASK_JSKC.getTaskId().equals(taskId);
        //委派目前只能是:技术踏勘
        if(isJSKC){
            //委派用户编辑
            List<Appoint> appoints = appointService.lambdaQuery().eq(Appoint::getUserId, userId).list();
            List<Appoint> collect = appoints.stream().filter(appoint -> {
                if (BizStageEnum.KAN_CHA.getStageId().equals(appoint.getStageId()) &&
                        BizTaskEnum.TASK_JSKC.getTaskId().equals(appoint.getTaskId()) &&
                        appoint.getOrderId().equals(orderId) &&
                        appoint.getUserId().equals(userId)) {
                    return true;
                }
                return false;
            }).collect(Collectors.toList());
            if(NullUtils.isNotEmpty(collect)){
                return true;
            }
            else {
                return false;
            }
        }

        return editList.stream().anyMatch(permission -> currentUser.getPermissionIds().contains(permission));
    }

    /**
     * 当前用户是否有权限
     */
    public boolean isCurrentUserHasPermission(String stageId, String taskId, List<String> approvalList) {
        Long userId = ServletUtils.getHeaderToLong(Constants.HEADER_USER_ID);

        //系统特殊配置用户
        if (configParams.getAllowUpdateOrderInfoUserIds().contains(String.valueOf(userId))) {
            return true;
        }
        if (StringUtils.isEmpty(approvalList)) {
            return false;
        }

        //购售电合同  必须是总部 先不管是不是商务审核员
        if (BizStageEnum.GS_CONTRACT.getStageId().equals(stageId) && BizTaskEnum.TASK_GSDHTXX.getTaskId().equals(taskId)) {
            if (!isUserBelongHeadCompany(userId)) {
                return false;
            }
        }
        //并网结算信息 或者 资料结算信息 必须是总部  先不管是不是财务审核员
        else if (BizStageEnum.SETTLEMENT.getStageId().equals(stageId)
                && (BizTaskEnum.TASK_BWJSXX.getTaskId().equals(taskId)
                || BizTaskEnum.TASK_ZLJSXX.getTaskId().equals(taskId))) {
            if (!isUserBelongHeadCompany(userId)) {
                return false;
            }
        }

        //匹配用户权限
        List<Permissions> userPermission = btoPermissionService.getPermissionListByUserId(userId);
        return userPermission.stream().anyMatch(permissions -> approvalList.stream().anyMatch(item -> item.equals(permissions.getName())));
    }




    /**
     * 当前用户可查看的订单范围
     * 总部员工：看全部订单
     * 非总部员工：
     * 角色：业务主管  看全部 项目部
     * 权限：设计上传、技术勘察、施工上传、并网上传、财务上传员   商务审核、踏勘审核 看全部 项目部
     */
    public LambdaQueryWrapper<OrderBase> getCurrentUserOrderScopedLambdaQueryWrapper() {
        /**
         * 总部员工可以查看所有订单，分公司、项目部只能查看各自的
         */
        LambdaQueryWrapper<OrderBase> queryWrapper = new LambdaQueryWrapper<>();
        User currentUser = getCurrentUser();
        Company currentUserCompany = getUserCompany(currentUser.getUserId());
        //包含仓库权限不能看到订单
        boolean hasPermissionBySto = DBConstants.USER_STO_PER.stream().anyMatch(permission ->
                currentUser.getPermissionIds().contains(permission)
        );
        if (hasPermissionBySto) {
            queryWrapper.isNull(OrderBase::getCompanyId);
            return queryWrapper;
        }


        if (DBConstants.COMPANY_TYPE_HEAD_OFFICE.equals(currentUserCompany.getType())) {
            return queryWrapper;
        }
        //非总部
        else {
            boolean hasRole = DBConstants.SUB_COMPANY_ALLOW_ALL_ORDER_ROLE_LIST.stream().anyMatch(role ->
                    currentUser.getRolesIds().contains(role)
            );

            boolean hasPermission = DBConstants.SUB_COMPANY_ALLOW_ALL_ORDER_PER_LIST.stream().anyMatch(permission ->
                    currentUser.getPermissionIds().contains(permission));
            //符合角色或者权限
            if (hasRole || hasPermission) {
                queryWrapper.eq(OrderBase::getCompanyId, currentUser.getCompanyId());
            }
            //业务员
            else {
                queryWrapper.eq(OrderBase::getUserId, currentUser.getUserId());
            }
        }
        return queryWrapper;
    }

    public List<String> currentUserOrderIdsScoped() {
        /**
         * 总部员工可以查看所有订单，分公司、项目部只能查看各自的
         */
        LambdaQueryWrapper<OrderBase> wrapper = getCurrentUserOrderScopedLambdaQueryWrapper();
        wrapper.select(OrderBase::getOrderId);
        return orderService.list(wrapper)
                .stream().map(OrderBase::getOrderId).collect(Collectors.toList());
    }

    /**
     * 当前用户是否有权限
     */
    public boolean isCurrentUserHasPermission(String... needPermission) {
        Long userId = ServletUtils.getHeaderToLong(Constants.HEADER_USER_ID);

        //系统特殊配置用户
        if (configParams.getAllowUpdateOrderInfoUserIds().contains(String.valueOf(userId))) {
            return true;
        }
        if (StringUtils.isEmpty(needPermission)) {
            return false;
        }

        //匹配用户权限
        List<Permissions> userPermission = btoPermissionService.getPermissionListByUserId(userId);
        return userPermission.stream().anyMatch(permissions -> Arrays.stream(needPermission).anyMatch(item -> item.equals(permissions.getName())));
    }

    /**
     * 根据权限查询用户
     */
    public List<User> getUsersByPermission(List<String> permissions, String orderId) {
        List<User> users = new ArrayList<User>();
        OrderBase orderBase = null;
        Long companyId;
        if (StringUtils.isNotBlank(orderId)) {
            orderBase = orderService.getById(orderId);
            if (null == orderBase) {
                throw new BizException("订单{}不存在", orderId);
            }
            companyId = orderBase.getCompanyId();

        } else {
            companyId = null;
        }
        permissions.forEach(permission -> {
            List<User> pUsers = userService.lambdaQuery()
                    .eq(User::getApprove, DBConstants.USER_APPROVE_PASS)//通过
                    .eq(User::getStatus, DBConstants.USER_STATUS_NORMAL)//正常
                    .eq(NullUtils.isNotNull(companyId), User::getCompanyId, companyId)//公司ID
                    .like(User::getPermissionIds, permission).list();
            users.addAll(pUsers);
        });
        return users;
    }

    /**
     * 根据角色查询用户
     */
    public List<User> getUsersByRole(String Role) {
        return userService.lambdaQuery()
                .like(User::getRolesIds, Role).list();
    }

    /**
     * 修改密码
     */
    public void updatePassword(UpdatePasswordReq updatePasswordReq) {
        if (updatePasswordReq == null) {
            throw new BizException(BizCode.PARAM_ERROR);
        }

        User loginUser = getCurrentUser();
        if (loginUser == null) {
            throw new BizException(BizCode.USER_ABSENT_ERROR);
        }

        if (Constants.ORIGIN_PASSWORD.equals(updatePasswordReq.getType())) {

            //输入的原密码
            String originPassword = updatePasswordReq.getOriginPassword();
            //登陆者的当前密码
            String passwordByLoginUser = loginUser.getPassword();

            if (StringUtils.isBlank(originPassword)
                    || updatePasswordReq.getNewPassword().length() < Constants.PASSWORD_LENGTH) {
                throw new BizException("原密码不能为空 或者 新密码长度不能小于6位");
            }
            //验证输入原密码与登录者的当前密码
            if (!originPassword.equals(passwordByLoginUser)) {
                throw new BizException("原密码错误，请输入正确的原密码");
            }

        } else if (Constants.SMS_PASSWORD.equals(updatePasswordReq.getType())) {

            //修改密码的验证码
            String code = updatePasswordReq.getCode();
            if (StringUtils.isBlank(code)
                    || updatePasswordReq.getNewPassword().length() < Constants.PASSWORD_LENGTH) {
                throw new BizException("验证码不能为空 或者 新密码长度不能小于6位");
            }
            //校验验证码
            isUpdateByCode(code, loginUser.getPhone());

        } else {
            throw new BizException(BizCode.PARAM_ERROR);
        }

        //更新用户密码信息
        LambdaUpdateWrapper<User> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(User::getUserId, loginUser.getUserId()).set(User::getPassword, updatePasswordReq.getNewPassword());
        userService.update(null, updateWrapper);
    }

    /**
     * 校验修改密码的验证码
     */
    private void isUpdateByCode(String passwordCode, String phone) {
        String code = redisService.getCacheObject(Constants.SMS_CODE_PASSWORD_KEY + phone);
        if (StringUtils.isEmpty(code)) {
            throw new BizException("验证码已过期，请输入重新获取验证码");
        }
        if (!passwordCode.equals(code)) {
            throw new BizException("验证码错误，请输入正确的验证码");
        }
        redisService.deleteObject(Constants.SMS_CODE_PASSWORD_KEY + phone);
    }

    /**
     * 校验输入的手机号与登陆者手机号
     */
    public void isUserByPhone(String phone) {
        User loginUser = getCurrentUser();
        if (null == loginUser) {
            throw new BizException(BizCode.USER_ABSENT_ERROR);
        }
        if (!loginUser.getPhone().equals(phone)) {
            throw new BizException("手机号不正确，可能与注册手机号不匹配！");
        }
    }

    //校验是否有权限修改超级管理员
    public void isSuperAdminByUpdate(User updateUser, User loginUser) {
        //修改者是超级管理员
        if (isUserSuperAdmin(updateUser)) {
            //登录者不是超级管理员
            if (!isUserSuperAdmin(loginUser)) {
                throw new BizException("修改用户：{}为超级管理员，登录用户：{}为不是超级管理员,无法操作！", updateUser.getUserId(), loginUser.getUserId());
            }
        }
    }


}
